#ifndef JANNA_LIBS_EXTENSIONSYSTEM_PLUGIN_MANAGER_H_
#define JANNA_LIBS_EXTENSIONSYSTEM_PLUGIN_MANAGER_H_

#include <spdlog/logger.h>

#include <QObject>
#include <QString>

#include "janna/libs/extensionsystem/iplugin.h"
namespace janna {

/**
 * @brief plugins.json 中的插件信息
 */
class PluginItem : public QObject {
    Q_OBJECT
public:
    PluginItem()           = default;
    ~PluginItem() override = default;

public:
    [[nodiscard]] QString id() const;
    void                  id(QString&& id);

    [[nodiscard]] QString version() const;
    void                  version(QString&& version);

    [[nodiscard]] QString path() const;
    void                  path(QString&& path);

    [[nodiscard]] bool enable() const;
    void               setEnable(bool enable);

private:
    /**
     * @brief 插件 id
     */
    QString m_id;
    /**
     * @brief 插件版本
     */
    QString m_version;
    /**
     * @brief 插件路径
     */
    QString m_path;
    /**
     * @brief 插件是否启用
     */
    bool m_enable{false};
};

class PluginManager : public QObject {
    Q_OBJECT
public:
    static PluginManager* getInstance();

    PluginManager();
    ~PluginManager() override = default;

private:
    std::shared_ptr<spdlog::logger> log;

private:
    /**
     * @brief 缓存所有插件
     */
    QMap<QString, JannaPluginInterface*> m_plugin_map;

    /**
     * @brief 加载单个插件
     *
     * @param pluginPath 当前插件路径
     * @param item 插件配置信息
     * @return true 加载成功
     * @return false 加载失败
     */
    bool loadSinglePlugin(const QString& pluginPath, PluginItem* item);

    /**
     * @brief 解析插件元数据
     * 
     * @param currPlugin 当前加载的插件
     * @param pluginPath 当前插件路径
     * @param item 当前插件信息
     * @return true 解析成功
     * @return false 解析失败
     */
    bool parseMetadata(JannaPluginInterface* currPlugin, const QString& pluginPath, PluginItem* item);

    /**
     * @brief 解析插件配置文件
     * 
     * @param pluginConfigPath 插件配置文件路径 
     * @return QList<PluginItem> 插件列表配置信息
     */
    QList<PluginItem*> parsePluginItems(const QString& pluginConfigPath);

public:
    /**
     * @brief 加载插件列表
     * 
     * @param pluginPath 插件列表配置文件路径
     */
    void loadPlugins(const QString& pluginPath);

public slots:
    /**
     * @brief 订阅 pubsub 消息
     * 
     * @param topic 主题
     * @param param 参数
     */
    void subscribe(const JannaTopic& topic, const QMap<QString, QVariant>& param);
};

};  // namespace janna

#endif